package com.bolt.report.engine.export.pdf;

import com.bolt.report.definition.BorderDefinition;
import com.bolt.report.definition.BorderType;
import com.bolt.report.definition.StyleDefinition;
import com.bolt.report.engine.model.Cell;
import com.bolt.report.engine.model.Table;
import com.bolt.report.util.StyleUtil;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPCellEvent;
import com.itextpdf.text.pdf.PdfPTable;

import java.math.BigDecimal;
import java.math.RoundingMode;


public class PdfCellBorderEvent implements PdfPCellEvent {

    private Table table;

    private Cell currentCell;

    public PdfCellBorderEvent(Table table, Cell currentCell) {
        this.table = table;
        this.currentCell = currentCell;
    }

    @Override
    public void cellLayout(PdfPCell pdfPCell, Rectangle position, PdfContentByte[] canvases) {

        StyleDefinition cellStyle = currentCell.getStyle();

        BorderDefinition leftBorder = cellStyle.getLeftBorder();

        if (leftBorder != null) {


            PdfContentByte cb = buildCellBorder(canvases, leftBorder);
            cb.moveTo(position.getLeft(), position.getTop());
            cb.lineTo(position.getLeft(), position.getBottom());
            cb.stroke();
            if (leftBorder.getStyle().equals(BorderType.doublesolid)) {
                cb.moveTo(position.getLeft() + 2, position.getTop() - 2);
                cb.lineTo(position.getLeft() + 2, position.getBottom() + 2);
                cb.stroke();
            }
            cb.restoreState();
        }
        BorderDefinition topBorder = cellStyle.getTopBorder();

        if (topBorder != null ) {
            PdfContentByte cb = buildCellBorder(canvases, topBorder);
            cb.moveTo(position.getLeft(), position.getTop());
            cb.lineTo(position.getRight(), position.getTop());
            cb.stroke();
            if (topBorder.getStyle().equals(BorderType.doublesolid)) {
                cb.moveTo(position.getLeft() + 2, position.getTop() - 2);
                cb.lineTo(position.getRight() - 2, position.getTop() - 2);
                cb.stroke();
            }
            cb.restoreState();
        }
        BorderDefinition rightBorder = cellStyle.getRightBorder();

        if (rightBorder != null  ) {
            PdfContentByte cb = buildCellBorder(canvases, rightBorder);
            cb.moveTo(position.getRight(), position.getTop());
            cb.lineTo(position.getRight(), position.getBottom());
            cb.stroke();
            if (rightBorder.getStyle().equals(BorderType.doublesolid)) {
                cb.moveTo(position.getRight() - 2, position.getTop() - 2);
                cb.lineTo(position.getRight() - 2, position.getBottom() + 2);
                cb.stroke();
            }
            cb.restoreState();
        }
        BorderDefinition bottomBorder = cellStyle.getBottomBorder();

        if (bottomBorder != null ) {
            PdfContentByte cb = buildCellBorder(canvases, bottomBorder);
            cb.moveTo(position.getLeft(), position.getBottom());
            cb.lineTo(position.getRight(), position.getBottom());
            cb.stroke();
            if (bottomBorder.getStyle().equals(BorderType.doublesolid)) {
                cb.moveTo(position.getLeft() + 2, position.getBottom() + 2);
                cb.lineTo(position.getRight() - 2, position.getBottom() + 2);
                cb.stroke();
            }
            cb.restoreState();
        }
    }

    private boolean existBorder(Cell cell, String position) {
        if (null == cell) {
            return false;
        }
        if (null == cell.getStyle()) {
            return false;
        }
        switch (position) {
            case "left":
                return cell.getStyle().getLeftBorder() != null;
            case "top":
                return cell.getStyle().getTopBorder() != null;
            case "right":
                return cell.getStyle().getRightBorder() != null;
            case "bottom":
                return cell.getStyle().getBottomBorder() != null;
            default:
                return false;
        }
    }

    private PdfContentByte buildCellBorder(PdfContentByte[] canvases, BorderDefinition border) {
        PdfContentByte cb = canvases[PdfPTable.LINECANVAS];
        cb.saveState();
        BigDecimal w = new BigDecimal(border.getWidth());
        cb.setLineWidth(w.divide(new BigDecimal(2), 10, RoundingMode.HALF_UP).floatValue());
        if (border.getStyle().equals("dashed")) {
            cb.setLineDash(new float[]{2f, 3f, 1f}, 2);
        }

        int[] rgb = StyleUtil.hexColorToRgb(border.getColor());
        cb.setColorStroke(new BaseColor(rgb[0], rgb[1], rgb[2]));
        return cb;
    }
}